//导入express
const express = require('express')
const {application,request,response} = require('express')
const app = express()

//引入Mysql
const mysql =require('mysql')

//连接数据库
//创建连接
const db = mysql.createConnection({
    host:'127.0.0.1',
    user:'root',
    password:'yylovechao999',
    port:3306,
    database:'mood_diary'
})
//解决跨域的问题
//解决跨域问题
app.all('/*', function(req, res, next) {
    res.header('Access-Control-Allow-Origin', '*')
    res.header('Access-Control-Allow-Headers', 'X-Requested-With, mytoken')
    res.header('Access-Control-Allow-Headers', 'X-Requested-With, Authorization')
    res.setHeader('Content-Type', 'application/json;charset=utf-8')
    res.header('Access-Control-Allow-Headers', 'Content-Type,Content-Length, Authorization, Accept,X-Requested-With')
    res.header('Access-Control-Allow-Methods', 'PUT,POST,GET,DELETE,OPTIONS')
    res.header('X-Powered-By', ' 3.2.1')
    if (req.method == 'OPTIONS') res.send(200)
    /*让options请求快速返回*/ else next()
})

/**
 * 生成userId
 * userId打算用时间戳来生成 + 0-9的随机数来生成
 * 封装一个方法getUserId()来获取userId
 * @returns {number} userid
 */
function getUserId(){
    var date = new Date()
    /**
     * 获取时间戳
     */
    var dateline = date.getTime().toString()
    /**
     *  console.log("时间戳长度为:"+dateline.length)
     *  截取时间戳的第6-13位
     */
    var shortDate = dateline.substring(6,13)
   /*
    console.log("原始时间戳为："+dateline)
    console.log("截取之后的数字为："+shortDate)
    */
    //生成随机数
    var randomNumber = Math.floor(Math.random()*10)
    //console.log("随机数字为:"+randomNumber)
    var userid = parseInt((randomNumber+shortDate))
    /*console.log("最终的userId为:"+userId)
    console.log("userId类型是:"+typeof userId)*/
    return userid
}

/**
 * 生成文章id
 */
function getArticleId(){
    var date = new Date()
    /**
     * 获取时间戳
     */
    var dateline = date.getTime().toString()
    /**
     *  console.log("时间戳长度为:"+dateline.length)
     *  截取时间戳的第6-13位
     */
    var shortDate = dateline.substring(7,13)
    /*
     console.log("原始时间戳为："+dateline)
     console.log("截取之后的数字为："+shortDate)
     */
    //生成随机数
    var randomNumber = Math.floor(Math.random()*10)
    //console.log("随机数字为:"+randomNumber)
    var articleId = parseInt((randomNumber+shortDate))
    /*console.log("最终的userId为:"+userId)
    console.log("userId类型是:"+typeof userId)*/
    return articleId
}
/**
 * 需要生成userId的时候就调用该函数
 * var res = getUserId()
*/

/**
 * 测试接口，连接数据库，简单查询
 */
app.get('/getdata',(requset,response)=>{
        //连接数据库，执行查询
        const sql = 'SELECT * FROM login_table'
        db.query(sql,(err,result)=>{
            if(err){
                console.log(err)
            }else{
                console.log(result)
                response.send(result)
            }
        })
})
/**
 * 加密算法
 */
function toCode(str) {  //加密字符串
    //定义密钥，36个字母和数字
    let key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let l = key.length;  //获取密钥的长度
    let a = key.split("");  //把密钥字符串转换为字符数组
    let s = "",b, b1, b2, b3;  //定义临时变量
    for (let i = 0; i <str.length; i ++) {  //遍历字符串
        b = str.charCodeAt(i);  //逐个提取每个字符，并获取Unicode编码值
        b1 = b % l;         //求Unicode编码值得余数
        b = (b - b1)/l;     //求最大倍数
        b2 = b % l;         //求最大倍数的于是
        b = (b - b2)/l;     //求最大倍数
        b3 = b % l;         //求最大倍数的余数
        s += a[b3] + a[b2] + a[b1];  //根据余数值映射到密钥中对应下标位置的字符
    }
    return s;  //返回这些映射的字符
}
/**
 * 解密算法
 */
function fromCode(str) {
    //定义密钥，36个字母和数字
    let key = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    let l = key.length;  //获取密钥的长度
    let b, b1, b2, b3, d = 0, s;  //定义临时变量
    s = new Array(Math.floor(str.length / 3));  //计算加密字符串包含的字符数，并定义数组
    b = s.length;  //获取数组的长度
    for (let i = 0; i < b; i ++) {  //以数组的长度循环次数，遍历加密字符串
        b1 = key.indexOf(str.charAt(d));  //截取周期内第一个字符串，计算在密钥中的下标值
        d ++;
        b2 = key.indexOf(str.charAt(d));  //截取周期内第二个字符串，计算在密钥中的下标值
        d ++;
        b3 = key.indexOf(str.charAt(d));  //截取周期内第三个字符串，计算在密钥中的下标值
        d ++;
        s[i] = b1 * l * 1 + b2 * l + b3  //利用下标值，反推被加密字符的Unicode编码值
    }
    b = eval("String.fromCharCode(" + s.join(',') + ")");//用fromCharCode()算出字符串
    return b ;  //返回被解密的字符串
}

/**
 * 封装时间转换格式
 */
Date.prototype.Format = function (fmt) {
    var o = {
        "M+": this.getMonth() + 1, //月份
        "d+": this.getDate(), //日
        "h+": this.getHours(), //小时
        "m+": this.getMinutes(), //分
        "s+": this.getSeconds(), //秒
        "q+": Math.floor((this.getMonth() + 3) / 3), //季度
        "S": this.getMilliseconds() //毫秒
    };
    if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
    for (var k in o)
        if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
    return fmt;
}

/**
 * 封装一下getTime函数
 */
function getTime(){
    let date = new Date()
    let nowTime = date.Format("yyyy-MM-dd hh:mm:ss")
    return nowTime
}
//调用方法
// console.log(getTime())
/**
 * 注册账号接口
 */
app.get('/register/',(request,response)=>{
    const  userId = getUserId()         //生成userId
    console.log("生成的userId为："+userId)
    //先创建对象接收参数
    let regParams = {
        userId:userId,
        username:request.query.username,
        //调用加密函数进行加密
        password:toCode(request.query.password)
    }
    //定义一个成功状态标志对象
    var status_s = {
        meta:'昵称可用',
        status:200
    }
    //定义一个失败状态标志对象
    var status_f = {
        meta:'昵称重复，不可用,请换一个昵称试试！',
        status:201
    }
    console.log(userId,regParams.username,regParams.password)
    /**
     * 在执行插入语句之前，先执行查询语句，如果数据库中有相同的用户名，则注册失败
     */
    const mysql_select = `SELECT * FROM login_table WHERE username = '${regParams.username}'`
    db.query(mysql_select,(err,result)=>{
        if(err){
            throw err
        }else {
            /**
             * 如果查询到的是一个空对象，那么证明没有改记录，可以继续注册
             * 如果不是空对象，则查询成功，昵称重复，不可以注册，得换一个昵称
             */
            let arr = Object.keys(result)
            if(arr.length == 0){
                console.log("昵称可用！")
                /**
                 * sql语句插入向表中插入账户和密码
                 */
                const mysql = `INSERT INTO login_table (user_id,username,password) 
                   VALUES ('${regParams.userId}','${regParams.username}','${regParams.password}')`
                //执行插入操作
                db.query(mysql,(err,res)=>{
                    if(err){
                        throw err
                    }else {
                        console.log(res)
                    }
                })
                response.send(status_s)
            }else {
                console.log("昵称重复，不可用")
                response.send(status_f)
            }
        }
    })
})

/**
 * 登录接口
 */
app.get('/login',(request,response)=>{
    /**
     * 先执行查询，如果数据库没有该账户名，则提醒注册
     */
    let login_form = {
        username: request.query.username,
        password: request.query.password
    }
    //设置状态
    let result_f_r = {
        meta:"查询不到该账号，请注册后登录！",
        status:201
    }
    // let result_s = {
    //     meta:"登录成功！",
    //     status:200,
    // }
    // let result_f = {
    //     meta:"密码输入错误，请输入正确密码登录！",
    //     status:202
    // }
    //执行查询
    const sql = `SELECT * FROM login_table WHERE username = '${login_form.username}'`
    db.query(sql,(err,result)=>{
        if(err){
            throw err
        }else{
            //如果查询结果为空，则返回一个空结果的信号给前端
            let arr = Object.keys(result)
            if(arr.length == 0){
                response.send(result_f_r)
            }else{
                console.log(result)
                let result_s = {
                    meta:"登录成功！",
                    status:200,
                    user_id:result[0].user_id
                }
                let result_f = {
                    meta:"密码输入错误，请输入正确密码登录！",
                    status:202
                }
                //把输入框内的密码和数据库中的密码解密之后进行比对
                console.log("明文密码为:"+fromCode(result[0].password))
                // console.log(result[0].user_id)
                if(login_form.password == fromCode(result[0].password)){
                    response.send(result_s)
                }else {
                    response.send(result_f)
                }
            }
        }
    })
})

/**
 * 更改密码接口
 */
app.get('/updatePwd',(request,response)=>{
    let update_from={
        username:request.query.username,
        password:request.query.password
    }
    /**
     * 先去数据查一下是否存在该账号
     * */
    const sql = `SELECT * FROM login_table WHERE username = '${update_from.username}'`
    db.query(sql,(err,result)=>{
        if(err){
            throw err
        }else{
            /**
             *  查询成功
             *  判断是否为空
             */
            let arr = Object.keys(result)
            if(arr.length == 0){
                response.send({
                    status:202,
                    meta:'无此账号！更改失败'
                })
            }else {
                //先对前端提供的密码进行加密
                let update_password = toCode(update_from.password)
                //更新SQL语句
                const sql_update = `UPDATE login_table SET password='${update_password}'
                                    WHERE username = '${update_from.username}'`
                db.query(sql_update,(err,res)=>{
                    if(err){
                        throw err
                    }else {
                        // console.log('更新成功')
                        response.send({
                            meta:"更改密码成功，请牢记密码！",
                            status:200
                        })
                    }
                })
            }
        }
    })
})
/**
 * 发表文章的接口
 */
app.get('/article',(request,response)=>{
    //生成文章的id，取时间戳的最后7位
    let articleId = getArticleId()
    let backTime = getTime()
    let article_form = {
        user_id: request.query.userId,
        article_id:articleId,
        article_visit_count:request.query.visit_count,
        article_pic:request.query.pic,
        article_date:backTime,
        article_content:request.query.content,
        article_permission:request.query.purview,
    }
//SQL语句
    const sql = `INSERT INTO  article_table(user_id,article_id,article_visit_count,article_pic,article_date,
                                    article_content,article_permission) VALUES (${article_form.user_id},${article_form.article_id},
                                    '${article_form.article_visit_count}','${article_form.article_pic}','${article_form.article_date}',
                                    '${article_form.article_content}','${article_form.article_permission}')`
    db.query(sql,(err,result)=>{
        if(err){
            throw err
        }else{
            console.log(result)
            response.send(result)
        }
    })
})
/**
 * 查询所有权限为1的文章
 */
app.get('/getArticle',(request,response)=>{
    const sql = `SELECT * FROM article_table WHERE article_permission = '1'`
    db.query(sql,(err,result)=>{
        if(err){
            throw err
        }else {
            console.log(result)
            response.send(result)
        }
    })
})
/**
 * 启动服务，监听端口
 */
app.listen(8086,()=>{
    console.log("后台服务器已经在8086端口上启动成功！")
})

